package com.example.expinterview.config;

import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.lang.NonNull;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;


/**
 * @author WangPeng
 * @version 2.0
 * @date 2021/6/11 11:12
 * @description web过滤器，生成日志链路追踪id，并赋值MDC
 */
@ConditionalOnClass(value = {HttpServletRequest.class, OncePerRequestFilter.class})
@Order(-1)
@Configuration
public class WebTraceFilter extends OncePerRequestFilter {



    @Override
    protected boolean shouldNotFilter(@NonNull HttpServletRequest request) {
        return false;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, @NonNull HttpServletResponse response,
                                    @NonNull FilterChain filterChain) throws IOException, ServletException {
        try {
            //方法
            String method = request.getMethod();
            //请求地址
            String servletPath = request.getServletPath();
            //URL 请求参数
            String requestParams = getRequestParams(request);
            //获取body 请求参数
            WrappedHttpServletRequest requestWrapper =
                    new WrappedHttpServletRequest(request);
            // 获取请求参数
            String requestBody = requestWrapper.getRequestParams();
            if (!StringUtils.isBlank(requestBody)) {
                if (requestBody.length() >= CustomConstant.HTTP_MAXIMUM_BYTE) {
                    requestBody = StringUtils.EMPTY;
                }
            }
            //url 参数
            String params = StringUtils.isBlank(requestParams) ? StringUtils.EMPTY : "&requestParams=" + requestParams;
            //body 参数
            String body = StringUtils.isBlank(requestBody) ? StringUtils.EMPTY : "&body=" + requestBody;
            //埋点
            logger.info("请求信息：servletPath=" + servletPath + params + "&method=" + method + body);
            // 这里doFilter传入我们实现的子类，request中的流只能读取一次。
            filterChain.doFilter(requestWrapper, response);
        } finally {
        }
    }

    /**
     * 获取请求地址上的参数
     * 只能处理路径上的参数body的参数需要另外处理
     *
     * @param request http请求
     * @return 请求参数
     */
    public static String getRequestParams(HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        Enumeration<String> enu = request.getParameterNames();
        // 获取请求参数
        while (enu.hasMoreElements()) {
            String name = enu.nextElement();
            sb.append(CustomConstant.SPLIT_AND).append(name).append(CustomConstant.SPLIT_STRING_M).append(request.getParameter(name));
        }
        return sb.toString();
    }
}
